package storages

import (
	"github.com/pkg/errors"
	"gluenet/internal/glue-srvm/model"
	"gorm.io/gorm"
)

type machineStorage struct{}

var DefaultMachineStorage = &machineStorage{}

func (c *machineStorage) Insert(db *gorm.DB, data model.MaasMachine) (uint, error) {
	return uint(data.Id), errors.WithStack(db.Create(&data).Error)
}

func (c *machineStorage) Update(db *gorm.DB, filter, data model.MaasMachine) error {
	return errors.WithStack(db.Model(data).Where(&filter).Updates(&data).Error)
}

func (c *machineStorage) DeleteByID(db *gorm.DB, id uint) error {
	if id == 0 {
		return errors.New("ID cannot be empty.")
	}
	return errors.WithStack(db.Delete(&model.MaasMachine{Id: uint64(id)}).Error)
}

func (c *machineStorage) FindOne(db *gorm.DB, filter model.MaasMachine) (*model.MaasMachine, error) {
	var machine model.MaasMachine
	err := db.Where(&filter).Find(&machine).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, nil
	}
	return &machine, errors.WithStack(err)
}

func (c *machineStorage) FindAll(db *gorm.DB, filter model.MaasMachine) ([]model.MaasMachine, error) {
	var machines []model.MaasMachine
	err := db.Where(&filter).Find(&machines).Error
	if err != nil && err == gorm.ErrRecordNotFound {
		return nil, errors.WithStack(err)
	}
	return machines, nil
}

func (c *machineStorage) FindList(db *gorm.DB, filter model.MaasMachine, accountID string) ([]model.MaasMachine, error) {
	var machines []model.MaasMachine
	db = db.Where("deleted_at IS NULL")
	db = db.Order("created_at DESC")
	db = db.Where("EXISTS (SELECT 1 from metering_account_to_host math WHERE math.host_id= `maas_machine`.id AND math.account_id=?)", accountID)
	return machines, db.Find(&machines).Error
}
